home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Id: amq.c,v 5.2 90/06/23 22:20:07 jsp Rel $
- *
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms are permitted provided
- * that: (1) source distributions retain this entire copyright notice and
- * comment, and (2) distributions including binaries display the following
- * acknowledgement: ``This product includes software developed by the
- * University of California, Berkeley and its contributors'' in the
- * documentation or other materials provided with the distribution and in
- * all advertising materials mentioning features or use of this software.
- * Neither the name of the University nor the names of its contributors may
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
- /*
- * Automounter query tool
- */
-
- #ifndef lint
- char copyright[] = "\
- @(#)Copyright (c) 1990 Jan-Simon Pendry\n\
- @(#)Copyright (c) 1990 Imperial College of Science, Technology & Medicine\n\
- @(#)Copyright (c) 1990 The Regents of the University of California.\n\
- @(#)All rights reserved.\n";
- #endif /* not lint */
-
- #ifndef lint
- static char rcsid[] = "$Id: amq.c,v 5.2 90/06/23 22:20:07 jsp Rel $";
- static char sccsid[] = "%W% (Berkeley) %G%";
- #endif /* not lint */
-
- #include "am.h"
- #include "amq.h"
- #include <stdio.h>
- #include <fcntl.h>
- #include <netdb.h>
-
- char *progname;
- static int flush_flag;
- static int minfo_flag;
- static int unmount_flag;
- static int stats_flag;
- static char *debug_opts;
- static char *logfile;
- static char *xlog_opt;
- static char localhost[] = "localhost";
- static char *def_server = localhost;
-
- extern int optind;
- extern char *optarg;
-
- static struct timeval tmo = { 10, 0 };
- #define TIMEOUT tmo
-
- enum show_opt { Full, Stats, Calc, Short, ShowDone };
-
- /*
- * If (e) is Calc then just calculate the sizes
- * Otherwise display the mount node on stdout
- */
- static void show_mti(mt, e, mwid, dwid, twid)
- amq_mount_tree *mt;
- enum show_opt e;
- int *mwid;
- int *dwid;
- int *twid;
- {
- switch (e) {
- case Calc: {
- int mw = strlen(mt->mt_mountinfo);
- int dw = strlen(mt->mt_directory);
- int tw = strlen(mt->mt_type);
- if (mw > *mwid) *mwid = mw;
- if (dw > *dwid) *dwid = dw;
- if (tw > *twid) *twid = tw;
- } break;
-
- case Full: {
- struct tm *tp = localtime(&mt->mt_mounttime);
- printf("%-*.*s %-*.*s %-*.*s %s\n\t%-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n",
- *dwid, *dwid,
- *mt->mt_directory ? mt->mt_directory : "/", /* XXX */
- *twid, *twid,
- mt->mt_type,
- *mwid, *mwid,
- mt->mt_mountinfo,
- mt->mt_mountpoint,
-
- mt->mt_mountuid,
- mt->mt_getattr,
- mt->mt_lookup,
- mt->mt_readdir,
- mt->mt_readlink,
- mt->mt_statfs,
-
- tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year,
- tp->tm_mon+1, tp->tm_mday,
- tp->tm_hour, tp->tm_min, tp->tm_sec);
- } break;
-
- case Stats: {
- struct tm *tp = localtime(&mt->mt_mounttime);
- printf("%-*.*s %-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n",
- *dwid, *dwid,
- *mt->mt_directory ? mt->mt_directory : "/", /* XXX */
-
- mt->mt_mountuid,
- mt->mt_getattr,
- mt->mt_lookup,
- mt->mt_readdir,
- mt->mt_readlink,
- mt->mt_statfs,
-
- tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year,
- tp->tm_mon+1, tp->tm_mday,
- tp->tm_hour, tp->tm_min, tp->tm_sec);
- } break;
-
- case Short: {
- printf("%-*.*s %-*.*s %-*.*s %s\n",
- *dwid, *dwid,
- *mt->mt_directory ? mt->mt_directory : "/",
- *twid, *twid,
- mt->mt_type,
- *mwid, *mwid,
- mt->mt_mountinfo,
- mt->mt_mountpoint);
- } break;
- }
- }
-
- /*
- * Display a mount tree.
- */
- static void show_mt(mt, e, mwid, dwid, pwid)
- amq_mount_tree *mt;
- enum show_opt e;
- int *mwid;
- int *dwid;
- int *pwid;
- {
- while (mt) {
- show_mti(mt, e, mwid, dwid, pwid);
- show_mt(mt->mt_next, e, mwid, dwid, pwid);
- mt = mt->mt_child;
- }
- }
-
- static void show_mi(ml, e, mwid, dwid, twid)
- amq_mount_info_list *ml;
- enum show_opt e;
- int *mwid;
- int *dwid;
- int *twid;
- {
- int i;
- switch (e) {
- case Calc: {
- for (i = 0; i < ml->amq_mount_info_list_len; i++) {
- amq_mount_info *mi = &ml->amq_mount_info_list_val[i];
- int mw = strlen(mi->mi_mountinfo);
- int dw = strlen(mi->mi_mountpt);
- int tw = strlen(mi->mi_type);
- if (mw > *mwid) *mwid = mw;
- if (dw > *dwid) *dwid = dw;
- if (tw > *twid) *twid = tw;
- }
- } break;
-
- case Full: {
- for (i = 0; i < ml->amq_mount_info_list_len; i++) {
- amq_mount_info *mi = &ml->amq_mount_info_list_val[i];
- printf("%-*.*s %-*.*s %-*.*s %-3d %s is %s",
- *mwid, *mwid, mi->mi_mountinfo,
- *dwid, *dwid, mi->mi_mountpt,
- *twid, *twid, mi->mi_type,
- mi->mi_refc, mi->mi_fserver,
- mi->mi_up > 0 ? "up" :
- mi->mi_up < 0 ? "starting" : "down");
- if (mi->mi_error > 0) {
- extern char *sys_errlist[];
- extern int sys_nerr;
- if (mi->mi_error < sys_nerr)
- printf(" (%s)", sys_errlist[mi->mi_error]);
- else
- printf(" (Error %d)", mi->mi_error);
- } else if (mi->mi_error < 0) {
- fputs(" (in progress)", stdout);
- }
- fputc('\n', stdout);
- }
- } break;
- }
- }
-
- /*
- * Display general mount statistics
- */
- static void show_ms(ms)
- amq_mount_stats *ms;
- {
- printf("\
- requests stale mount mount unmount\n\
- deferred fhandles ok failed failed\n\
- %-9d %-9d %-9d %-9d %-9d\n",
- ms->as_drops, ms->as_stale, ms->as_mok, ms->as_merr, ms->as_uerr);
- }
-
- static bool_t
- xdr_pri_free(xdr_args, args_ptr)
- xdrproc_t xdr_args;
- caddr_t args_ptr;
- {
- XDR xdr;
- xdr.x_op = XDR_FREE;
- return ((*xdr_args)(&xdr, args_ptr));
- }
-
- #ifdef hpux
- #include <cluster.h>
- static char *cluster_server()
- {
- struct cct_entry *cp;
-
- if (cnodeid() == 0) {
- /*
- * Not clustered
- */
- return def_server;
- }
-
- while (cp = getccent())
- if (cp->cnode_type == 'r')
- return cp->cnode_name;
-
-
- return def_server;
- }
- #endif /* hpux */
-
- /*
- * MAIN
- */
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int opt_ch;
- int errs = 0;
- char *server;
- struct sockaddr_in server_addr;
- int s = RPC_ANYSOCK;
- CLIENT *clnt;
- struct hostent *hp;
- int nodefault = 0;
-
- /*
- * Compute program name
- */
- if (argv[0]) {
- progname = strrchr(argv[0], '/');
- if (progname && progname[1])
- progname++;
- else
- progname = argv[0];
- }
- if (!progname)
- progname = "amq";
-
- /*
- * Parse arguments
- */
- while ((opt_ch = getopt(argc, argv, "fh:l:msux:D:")) != EOF)
- switch (opt_ch) {
- case 'f':
- flush_flag = 1;
- break;
-
- case 'h':
- def_server = optarg;
- break;
-
- case 'l':
- logfile = optarg;
- nodefault = 1;
- break;
-
- case 'm':
- minfo_flag = 1;
- nodefault = 1;
- break;
-
- case 's':
- stats_flag = 1;
- break;
-
- case 'u':
- unmount_flag = 1;
- break;
-
- case 'x':
- xlog_opt = optarg;
- nodefault = 1;
- break;
-
- case 'D':
- debug_opts = optarg;
- nodefault = 1;
- break;
-
- default:
- errs = 1;
- break;
- }
-
- if (errs) {
- show_usage:
- fprintf(stderr, "\
- Usage: %s [-h host] [[-f] [-m] | | [-s] | [[-u] directory ...]] |\n\
- \t[-l logfile|\"syslog\"] [-x log_flags] [-D dbg_opts]\n", progname);
- exit(1);
- }
-
- #ifdef hpux
- /*
- * Figure out root server of cluster
- */
- if (def_server == localhost)
- server = cluster_server();
- else
- #endif /* hpux */
- server = def_server;
-
- /*
- * Get address of server
- */
- if ((hp = gethostbyname(server)) == 0) {
- fprintf(stderr, "%s: Can't get address of %s\n", progname, server);
- exit(1);
- }
- bzero(&server_addr, sizeof server_addr);
- server_addr.sin_family = AF_INET;
- server_addr.sin_addr = *(struct in_addr *) hp->h_addr;
-
- /*
- * Create RPC endpoint
- */
- clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, TIMEOUT, &s);
- if (clnt == 0) {
- fprintf(stderr, "%s: ", progname);
- clnt_pcreateerror(server);
- exit(1);
- }
-
- /*
- * Control debugging
- */
- if (debug_opts) {
- int *rc;
- amq_setopt opt;
- opt.as_opt = AMOPT_DEBUG;
- opt.as_str = debug_opts;
- rc = amqproc_setopt_1(&opt, clnt);
- if (rc && *rc < 0) {
- fprintf(stderr, "%s: daemon not compiled for debug", progname);
- errs = 1;
- } else if (!rc || *rc > 0) {
- fprintf(stderr, "%s: debug setting for \"%s\" failed\n", progname, debug_opts);
- errs = 1;
- }
- }
-
- /*
- * Control logging
- */
- if (xlog_opt) {
- int *rc;
- amq_setopt opt;
- opt.as_opt = AMOPT_XLOG;
- opt.as_str = xlog_opt;
- rc = amqproc_setopt_1(&opt, clnt);
- if (!rc || *rc) {
- fprintf(stderr, "%s: setting log level to \"%s\" failed\n", progname, xlog_opt);
- errs = 1;
- }
- }
-
- /*
- * Control log file
- */
- if (logfile) {
- int *rc;
- amq_setopt opt;
- opt.as_opt = AMOPT_LOGFILE;
- opt.as_str = logfile;
- rc = amqproc_setopt_1(&opt, clnt);
- if (!rc || *rc) {
- fprintf(stderr, "%s: setting logfile to \"%s\" failed\n", progname, logfile);
- errs = 1;
- }
- }
-
- /*
- * Flush map cache
- */
- if (logfile) {
- int *rc;
- amq_setopt opt;
- opt.as_opt = AMOPT_FLUSHMAPC;
- opt.as_str = "";
- rc = amqproc_setopt_1(&opt, clnt);
- if (!rc || *rc) {
- fprintf(stderr, "%s: amd on %s cannot flush the map cache\n", progname, server);
- errs = 1;
- }
- }
-
- /*
- * Mount info
- */
- if (minfo_flag) {
- int dummy;
- amq_mount_info_list *ml = amqproc_getmntfs_1(&dummy, clnt);
- if (ml) {
- int mwid = 0, dwid = 0, twid = 0;
- show_mi(ml, Calc, &mwid, &dwid, &twid);
- mwid++; dwid++; twid++;
- show_mi(ml, Full, &mwid, &dwid, &twid);
-
- } else {
- fprintf(stderr, "%s: amd on %s cannot provide mount info\n", progname, server);
- }
- }
-
- /*
- * Apply required operation to all remaining arguments
- */
- if (optind < argc) {
- do {
- char *fs = argv[optind++];
- if (unmount_flag) {
- /*
- * Unmount request
- */
- amqproc_umnt_1(&fs, clnt);
- } else {
- /*
- * Stats request
- */
- amq_mount_tree_p *mtp = amqproc_mnttree_1(&fs, clnt);
- if (mtp) {
- amq_mount_tree *mt = *mtp;
- if (mt) {
- int mwid = 0, dwid = 0, twid = 0;
- show_mt(mt, Calc, &mwid, &dwid, &twid);
- mwid++; dwid++, twid++;
- #ifdef notdef
- printf("\t%s\n%-*.*s %-*.*s %-*.*s %s\n",
- "Uid Getattr Lookup RdDir RdLnk Statfs Mounted@",
- dwid, dwid, "What", twid, twid, "Type", mwid, mwid, "Info", "Where");
- show_mt(mt, Full, &mwid, &dwid, &twid);
- #endif /* notdef */
- printf("%-*.*s Uid Getattr Lookup RdDir RdLnk Statfs Mounted@\n",
- dwid, dwid, "What");
- show_mt(mt, Stats, &mwid, &dwid, &twid);
- } else {
- fprintf(stderr, "%s: %s not automounted\n", progname, fs);
- }
- xdr_pri_free(xdr_amq_mount_tree_p, (caddr_t) mtp);
- } else {
- fprintf(stderr, "%s: ", progname);
- clnt_perror(clnt, server);
- errs = 1;
- }
- }
- } while (optind < argc);
- } else if (unmount_flag) {
- goto show_usage;
- } else if (stats_flag) {
- amq_mount_stats *ms = amqproc_stats_1((voidp) 0, clnt);
- if (ms) {
- show_ms(ms);
- } else {
- fprintf(stderr, "%s: ", progname);
- clnt_perror(clnt, server);
- errs = 1;
- }
- } else if (!nodefault) {
- amq_mount_tree_list *mlp = amqproc_export_1((voidp) 0, clnt);
- if (mlp) {
- enum show_opt e = Calc;
- int mwid = 0, dwid = 0, pwid = 0;
- while (e != ShowDone) {
- int i;
- for (i = 0; i < mlp->amq_mount_tree_list_len; i++) {
- show_mt(mlp->amq_mount_tree_list_val[i],
- e, &mwid, &dwid, &pwid);
- }
- mwid++; dwid++, pwid++;
- if (e == Calc) e = Short;
- else if (e == Short) e = ShowDone;
- }
- } else {
- fprintf(stderr, "%s: ", progname);
- clnt_perror(clnt, server);
- errs = 1;
- }
- }
-
- exit(errs);
- }
-
- #ifdef DEBUG
- xfree(f, l, p)
- char *f, *l;
- voidp p;
- {
- free(p);
- }
- #endif /* DEBUG */
-